package com.vmj.common;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class BytesReader {
    
    private ByteBuffer buf;
    private int offset;

    public BytesReader() {
    }

    public BytesReader(byte[] data, ByteOrder order) {
        this.buf = ByteBuffer.wrap(data)
                .asReadOnlyBuffer()
                .order(order);
    }

    public int getPosition() {
        return buf.position();
    }

    public byte getByte(int index) {
        return buf.get(index);
    }

    public short getShort(int index) {
        return buf.getShort(index);
    }

    // 8-bit signed int
    public byte readByte() {
        byte b = buf.get(offset);
        offset++;
        return b;
    }
    
    // 8-bit unsigned int
    public int readUnsignedByte() {
        int d = (int)(buf.get(offset));
        offset++;
        return d;
    }
    
    // 16-bit signed int
    public short readShort() {
        short d = buf.getShort(offset);
        offset += 2;
        return d;
    }
    
    // 16-bit unsigned int
    public int readUnsignedShort() {
        int d = (int)(buf.getShort(offset));
        offset += 2;
        return d;
    }
    
    // 32-bit signed int
    public int readInt() {
        int d = buf.getInt(offset);
        offset += 4;
        return d;
    }

    // 32-bit unsigned int
    public long readUnsignedInt() {
        int d =  (int)(buf.getInt(offset));
        offset += 4;
        return d;
    }

    // 64-bit signed int
    public long readLong() {
        long d = buf.getLong(offset);
        offset += 8;
        return d;
    }

    public float readFloat() {
        float d = buf.getFloat(offset);
        offset += 4;
        return d;
    }

    public double readDouble() {
        double d = buf.getDouble(offset);
        offset += 8;
        return d;
    }

    // byte[]
    public byte[] readBytes(int n) {
        byte[] bytes = new byte[n];
        buf.position(offset);
        buf.get(bytes, 0, n);
        offset += n;
        return bytes;
    }

    public void skipBytes(int n) {
        for (int i = 0; i < n; i++) {
            buf.get();
        }
        offset += n;
    }

    public void reset(ByteBuffer buf, int offset) {
        this.buf = buf;
        this.offset = offset;
    }

    public void reset(byte[] buf, int offset) {
        this.buf = ByteBuffer.allocate(buf.length);
        this.buf.put(buf);
        this.offset = offset;
    }

    public int getOffset() {
        return offset;
    }

    public void skipPadding() {
        while( offset % 4 != 0) {
            readByte();
        }
    }

}
